package cc.rengu.igas.opms.core.service.trans.common;

import cc.rengu.igas.momp.facade.bean.PostPaymentAvailableCouponMcInfoBean;
import cc.rengu.igas.momp.facade.response.QueryAvailableDiscountInfoAfterPaymentResponse;
import cc.rengu.igas.momp.facade.result.Result;
import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.bean.DiscountInfo;
import cc.rengu.igas.opms.facade.request.DiscountInfoRequest;
import cc.rengu.igas.opms.facade.response.DiscountInfoResponse;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.common.constant.UserSessionConstant;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.OrderStatusEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;

import org.apache.commons.codec.binary.Base64;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 营销活动查询服务
 *
 * @author keyi
 * @modify by wangcheng
 * @date 2020/4/1.
 */
public class DiscountInfoService extends ManageService implements TransCustomImpl {

    @Override
    protected Object bizBeforeCust() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        DiscountInfoRequest discountInfoRequest = new DiscountInfoRequest();
        ConvertUtil.convertOutput(discountInfoRequest);
        if ("1".equals(discountInfoRequest.getUserType()) || "2".equals(discountInfoRequest.getUserType())) {
            /* 微信支付宝扫码特殊处理，先解密userId然后再Base64解码*/
            if (!StringUtil.isEmptyOrNull(discountInfoRequest.getUserId())) {
                UserService userService = new UserServiceImpl();
                String sensitiveKey = userService.getUserSessionValue(UserSessionConstant.SENSITIVE_KEY);
                if (StringUtil.isEmptyOrNull(sensitiveKey)) {
                    rglog.info("用户会话敏感信息密钥不存在,不对微信或支付宝用户标识进行解密处理!");
                    return discountInfoRequest;
                }
                String decryUserId = AESUtil.pkcs7CbcDecryptData(Base64.decodeBase64(sensitiveKey), Base64.decodeBase64(discountInfoRequest.getUserId()));
                rglog.debug("微信支付宝解密后的userId:<{}>", decryUserId);
                String userId = new String(Base64.decodeBase64(decryUserId.getBytes(StandardCharsets.UTF_8)));
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.USER_ID, userId);
                discountInfoRequest.setUserId(userId);
            }
        }
        return discountInfoRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {

        DiscountInfoRequest discountInfoRequest = (DiscountInfoRequest) request;
        DiscountInfoResponse discountInfoResponse = new DiscountInfoResponse();
        String instId = discountInfoRequest.getHeader().getInstId();
        String sessionId = discountInfoRequest.getHeader().getSession();
        String userId = discountInfoRequest.getUserId();
        String userOrderId = discountInfoRequest.getUserOrderId();

        //查找订单
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByUserOrderId(instId, userOrderId);
        if (userOrderInfo == null) {
            rglog.info("用户支付订单不存在");
            throw new BizException(RespCodeEnum.ORDER_NOEXIT.getRespCode(), RespCodeEnum.ORDER_NOEXIT.getRespDesc());
        }

        //判断订单状态
        if (!OrderStatusEnum.FINISH.getStatus().equals(userOrderInfo.getOrderStatus())
                || !TransStatusEnum.TRANS_SUCC.getStatus().equals(userOrderInfo.getTransStatus())) {
            rglog.info("用户订单未完成或订单未成功，orderStatus:<{}>,transStatus:<{}>", userOrderInfo.getOrderStatus(), userOrderInfo.getTransStatus());
            throw new BizException(RespCodeEnum.ORDER_STATUS_ERR.getRespCode(), RespCodeEnum.ORDER_STATUS_ERR.getRespDesc());
        }

        //调用营销接口查询
        if (null == txnInfo.getChannelCallCfgList() || txnInfo.getChannelCallCfgList().isEmpty()) {
            rglog.error("<{}-{}>交易未配置交易通道服务调用配置信息！", txnInfo.getSrcTxnAuthCfg().getTxnNum(), txnInfo.getSrcTxnAuthCfg().getTxnName());
            throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
        }
        List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item ->
                item.getCallIndex().equals(ChannelBaseService.FIRST_CHANNEL_CALL_INDEX)).collect(Collectors.toList());
        ChannelCallCfg channelCallCfg = channelCallSceneDiscern(discountInfoRequest, channelCallCfgList);
        Class channelClasz = Class.forName(channelCallCfg.getCallChannelImpl());
        ChannelBaseService channelBaseService = (ChannelBaseService) channelClasz.newInstance();
        channelBaseService.callService(txnInfo, null, channelCallCfg.getBizScene(), request);

        //设置标识控制用户只能领取一次优惠劵
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.SESSION_EXPIRY_TIMES);
        int sessionExpiryTime = (sysParam == null || StringUtil.isEmptyOrNull(sysParam.getParamValue())) ? OpmsParamConstant.SESSION_DEFAULT_TIMES : Integer.parseInt(sysParam.getParamValue());
        String key = sessionId + userId;
        RedisUtil.onceSet(key, AppParamConstant.NO, sessionExpiryTime);

        //获取优惠活动列表信息
        List<DiscountInfo> discountInfoList = (List<DiscountInfo>) GlobalTransUtil.getCacheValue(TransCacheConstant.DISCOUNT_INFO_LIST);
        discountInfoResponse.setDiscountInfoList(discountInfoList);

        //组响应
        BizResponse<DiscountInfoResponse> bizResponse = new BizResponse<>();
        bizResponse.setResult(discountInfoResponse);
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        DiscountInfoResponse discountInfoResponse = (DiscountInfoResponse) bizResponse.getResult();
        ConvertUtil.convertInput(discountInfoResponse);
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        Optional<ChannelCallCfg> channelCallCfgOpt = channelCallCfgList.stream().filter(item ->
                item.getBizScene().equals(ShareParamConstant.CALL_CFG_DEFAULT_BIZ_SCENE)).findFirst();
        return channelCallCfgOpt.orElse(null);
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return CheckResultEnum.PASSED;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        Result<QueryAvailableDiscountInfoAfterPaymentResponse> callResult = (Result<QueryAvailableDiscountInfoAfterPaymentResponse>) channelResponse;
        if (null != callResult && null != callResult.getResult() && null != callResult.getResult().getCouponInfoList()) {
            //解析响应信息
            ArrayList<DiscountInfo> discountInfoList = new ArrayList<>();
            List<PostPaymentAvailableCouponMcInfoBean> discountList = callResult.getResult().getCouponInfoList();
            for (PostPaymentAvailableCouponMcInfoBean bean : discountList) {
                //增加非空判断
                if (!StringUtil.isEmptyOrNull(bean.getMcNo())) {
                    DiscountInfo discountInfo = new DiscountInfo();
                    discountInfo.setMcNo(bean.getMcNo());
                    discountInfo.setRuleIndex(bean.getRuleIndex());
                    discountInfo.setDiscountId(bean.getCouponNo());
                    discountInfo.setDiscountDesc(bean.getRuleContent());
                    //使用门槛
                    discountInfo.setCriteria("");
                    discountInfo.setDiscountAmt(bean.getDenomination());
                    //开始日期 -营销接口改动
                    discountInfo.setStartDate(bean.getCouponStartDate());
                    //结束日期 -营销接口改动
                    discountInfo.setEndDate(bean.getCouponEndDate());
                    discountInfoList.add(discountInfo);
                }
            }
            GlobalTransUtil.setCacheValue(TransCacheConstant.DISCOUNT_INFO_LIST, discountInfoList);
        }
        return transStatusEnum;
    }
}
